package com.swu.cx.alwayslearning.myretrofit

import okhttp3.Call
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import java.lang.IllegalStateException
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import java.net.URL
import java.util.concurrent.ConcurrentHashMap

class MyRetrofit private constructor(
    val callFactory: Call.Factory,
    val baseUrl: HttpUrl
){

    private val serviceMethodCache = ConcurrentHashMap<Method, ServiceMethod>()

    fun <T> create(service: Class<T>): T {
        return Proxy.newProxyInstance(service.classLoader, arrayOf(service), object : InvocationHandler {
            override fun invoke(p0: Any, p1: Method, p2: Array<out Any>?): Any? {
                // 解析method上所有的注解信息
                val serviceMethod = loadServiceMethod(p1)
                if (p2 != null) {
                    return serviceMethod.invoke(p2)
                }
                return null
            }
        }) as T
    }

    private fun loadServiceMethod(method: Method): ServiceMethod {
        var res = serviceMethodCache[method]
        if (res != null) {
            return res
        }
        synchronized(serviceMethodCache) {
            res = serviceMethodCache[method]
            if (res == null) {
                res = ServiceMethod.Builder(this, method).build()
                serviceMethodCache[method] = res!!
            }
        }
        return res!!
    }

    class Builder {
        private var baseUrl: HttpUrl? = null
        fun baseUrl(baseUrl: String): Builder {
            this.baseUrl = HttpUrl.get(URL(baseUrl))
            return this
        }

        fun build(): MyRetrofit {
            if (baseUrl == null) {
                throw IllegalStateException("Base URL required!!!")
            }
            return MyRetrofit(OkHttpClient(), baseUrl!!)
        }
    }
}